﻿/**
 * \brief 处理线程定义
 * \file CRunningThread.cc
 */

#include "CTcpTask.h"
#include "CRunningThread.h"
#include "Log.h"
#include "CTaskPoolThreadType.h"

CRunningThread::CRunningThread(CTcpTaskPool* _pool, int _eventSize, std::string _threadName)
	: CTcpThread(_pool, _eventSize), CThread(_threadName)
{}

CRunningThread::~CRunningThread() {}

/**
 * \brief 线程主回调函数
 */
void CVerifyThread::run()
{
	_task_list_iter iter, next;

	while(this->isEnd())
	{
		/// 等待队列进入任务列表
		this->shift();

		if(!_M_list.empty())
		{
			for(iter = this->_M_list.begin(), next = iter; iter != this->_M_list.end();)
			{
				++next;
				CTcpTask* pTask = *iter;

				/// 连接信号是否有响应
				if(pTask->vCheckConnSignal())
				{
					pTask->setTerminal();
				}

				/// 任务是终止态，删除这个任务
				if(pTask->isTerminal())
				{
					this->remove(iter);
					pTask->setRecycle();
					this->_M_pool->addRecycle(pTask);
				}

				/// 迭代器后移
				if(next != this->_M_list.end())
				{
					iter = next++;
				}
				else
				{
					/// 循环结束
					break;
				}
			}
		}

		int retcode = ::epoll_wait(this->_M_epfd, &this->_M_events, this->_M_eventSize, 0);

		/// 循环处理epoll事件
		if(retcode > 0)
		{
			int pos = 0;
			for(; pos < retcode; ++pos)
			{
				CTcpTask* pTask = (CTcpTask*)this->_M_events[pos].data.ptr;
				if(this->_M_events[pos].events & (EPOLLERR | EPOLLPRI))
				{
					this->remove(pTask);
					pTask->setRecycle();
					this->_M_pool->addRecycle(pTask);
				}
				else
				{
					/// 策略：每次循环处理输入、输出事件
					if(this->_M_events[pos].events & EPOLLIN)
					{
						/// 读取数据到缓冲区
						pTask->onRecv();
					}
					else if(this->_M_events[pos].events & EPOLLOUT)
					{
						/// 发送数据到缓冲区
						pTask->onSend();
					}
				}
			}
		}
	}

	/// 线程结束，所有任务进入回收线程
	for(iter = this->_M_list.begin(), next = iter; iter != this->_M_list.end();)
	{
		++next;
		CTcpTask* pTask = *iter;

		/// 删除这个任务
		this->remove(iter);
		pTask->setRecycle();
		this->_M_pool->addRecycle(pTask);

		/// 迭代器后移
		if(next != this->_M_list.end())
		{
			iter = next++;
		}
		else
		{
			/// 循环结束
			break;
		}
	}
}

/**
 * \brief 加入任务列表
 * \param _pTask：任务指针
 */
void CVerifyThread::add(CTcpTask* _pTask)
{
	this->_M_list.push_back(_pTask);
	_pTask->addEpoll(this->_M_epfd, EPOLLIN | EPOLLOUT | EPOLLERR | EPOLLPRI, (void*)(*iter));
	this->_M_eventSize = this->_M_list.size();
}

/**
 * \brief 从任务列表删除
 * \param _iter：任务迭代器
 */
void CVerifyThread::remove(_task_list_iter& _iter)
{
	if(_iter != this->_M_list.end())
	{
		(*_iter)->delEpoll(this->_M_epfd, EPOLLIN | EEPOLLOUT | POLLERR | EPOLLPRI);
		this->_M_list.erase(iter);
		this->_M_eventSize = this->_M_list.size();
	}
}
